//******************************************************************
//******************************************************************
//**********          ANts Peer To Peer Sources        *************
//
// ANts P2P realizes a third generation P2P net. It protects your
// privacy while you are connected and makes you not trackable, hiding
// your identity (ip) and crypting everything you are sending/receiving
// from others.

// Copyright (C) 2004  Roberto Rossi

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

package ants.p2p.gui;

import java.awt.*;
import java.beans.*;
import javax.swing.*;
import com.borland.jbcl.layout.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;

import org.apache.log4j.*;

import ants.p2p.filesharing.*;
import ants.p2p.utils.indexer.*;
import java.awt.event.*;

public class ShareAntPanel extends JPanel implements PropertyChangeListener{
  public static String pic = "backgrounds/bg6.jpg";

  static Logger _logger = Logger.getLogger(ShareAntPanel.class.getName());

  static int[] columnSizes = {500,150,100,300,300};

  GuiAnt caller;
  Image buffer;
  JPanel jPanel1 = new JPanel();
  XYLayout xYLayout1 = new XYLayout();
  Border border1;
  JButton jButton2 = new JButton();
  JLabel jLabel2 = new JLabel();
  JButton jButton1 = new JButton();
  JList jList1 = new JList();
  JScrollPane jScrollPane2 = new JScrollPane();
  JScrollPane jScrollPane1 = new JScrollPane();
  JTable sharedFilesTable;
  JLabel jLabel1 = new JLabel();
  JLabel jLabel3 = new JLabel();
  JPanel jPanel2 = new JPanel();
  FlowLayout flowLayout1 = new FlowLayout();
  Border border2;
  Border border3;
  XYLayout xYLayout2 = new XYLayout();
  Border border4;
  Border border5;
  JProgressBar jProgressBar1 = new JProgressBar();
  JLabel jLabel4 = new JLabel();
  JLabel jLabel5 = new JLabel();
  JCheckBox jCheckBox1 = new JCheckBox();
  JButton jButton3 = new JButton();
  FocusListener focusListener = new SharedFiles_editor_focusAdapter(this);
  int editedRow = -1;
  JCheckBox jCheckBox2 = new JCheckBox();

  public ShareAntPanel(GuiAnt caller) {
    this.caller = caller;
    try{
      Toolkit tk = Toolkit.getDefaultToolkit();
      MediaTracker mt = new MediaTracker(this);
      buffer = tk.getImage(this.getClass().getClassLoader().getResource(pic));
      mt.waitForAll();
    }catch(Exception e){}
    try {
      jbInit();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
    BackgroundEngine be = BackgroundEngine.getInstance();
    be.addPropertyChangeListener(this);
    be.forceExternalUpdate();
  }
  void jbInit() throws Exception {
    border1 = BorderFactory.createEmptyBorder(20,20,20,20);
    border2 = BorderFactory.createEmptyBorder(0,5,0,5);
    border3 = BorderFactory.createEmptyBorder(20,20,20,20);
    border4 = BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151)),BorderFactory.createEmptyBorder(5,5,5,5));
    border5 = BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151)),BorderFactory.createEmptyBorder(5,5,5,5));
    this.setLayout(flowLayout1);
    jPanel1.setLayout(xYLayout1);
    jPanel1.setBorder(border4);
    jPanel1.setDebugGraphicsOptions(0);
    jPanel1.setDoubleBuffered(true);
    jPanel1.setMinimumSize(new Dimension(220, 270));
    jPanel1.setPreferredSize(new Dimension(600, 270));
    this.addComponentListener(new ShareAntPanel_this_componentAdapter(this));
    jButton2.setMaximumSize(new Dimension(120, 50));
    jButton2.setMinimumSize(new Dimension(120, 50));
    jButton2.setPreferredSize(new Dimension(120, 50));
    jButton2.setToolTipText(ji.JI.i("Remove the selected directory from the shared group"));
    //jButton2.setText(ji.JI.i("Remove"));
    jButton2.setIcon(new LabelIcon(ji.JI.i("Remove"),DoubleBuffer.getInstance().getButton(3), jButton2));
    jButton2.addActionListener(new ShareAntPanel_jButton2_actionAdapter(this));
    jLabel2.setText(ji.JI.i("Shared Directories"));
    jButton1.setMaximumSize(new Dimension(120, 50));
    jButton1.setMinimumSize(new Dimension(120, 50));
    jButton1.setPreferredSize(new Dimension(120, 50));
    jButton1.setToolTipText(ji.JI.i("Add a directory to the shared group"));
    //jButton1.setText(ji.JI.i("Add"));
    jButton1.setIcon(new LabelIcon(ji.JI.i("Add"),DoubleBuffer.getInstance().getButton(0), jButton1));
    jButton1.addActionListener(new ShareAntPanel_jButton1_actionAdapter(this));
    jList1.setFont(new java.awt.Font("Monospaced", 0, 11));
    jList1.setOpaque(true);
    jList1.setToolTipText(ji.JI.i("These are your currently shared directories, if you select recursive " +
    "also their subdirectories will be shared too"));
    jScrollPane2.setOpaque(true);
    jScrollPane2.setPreferredSize(new Dimension(400, 130));
    jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    jScrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    jScrollPane1.setDebugGraphicsOptions(0);
    jScrollPane1.setToolTipText(ji.JI.i("These are your currently shared files, right click for options"));
    jLabel1.setText(ji.JI.i("Shared Files"));
    jLabel3.setToolTipText(ji.JI.i("Indexing status, the indexing process can be heavy, choose a proper " +
    "moment to perform it"));
    jLabel3.setText(ji.JI.i("Status")+": ");
    jPanel2.setLayout(xYLayout2);
    this.setBorder(border1);
    jPanel2.setBorder(border5);
    SharedFilesTableModel model = new SharedFilesTableModel(new ArrayList());
    TableSorter sorter = new TableSorter(model);
    sharedFilesTable = new JTable(sorter);
    sorter.setTableHeader(sharedFilesTable.getTableHeader());
    sharedFilesTable.getTableHeader().setToolTipText(ji.JI.i("Click to specify sorting; Control-Click to specify secondary sorting"));
    sharedFilesTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    sharedFilesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    sharedFilesTable.setGridColor(new java.awt.Color(0,0,0,0));
    sharedFilesTable.addMouseListener(new ShareAntPanel_sharedFilesTable_mouseAdapter(this));
    sharedFilesTable.setFont(new java.awt.Font("Monospaced", 0, 11));
    jLabel4.setText(ji.JI.i("Indexing file"));
    jLabel4.setVisible(false);
    this.jProgressBar1.setMaximum(100);
    this.jProgressBar1.setMinimum(0);
    this.jProgressBar1.setVisible(false);
    jCheckBox1.setText(ji.JI.i("Recursive"));
    jCheckBox1.setPreferredSize(new Dimension(180, 23));
    jCheckBox1.setToolTipText(ji.JI.i("Share subdirectories"));
    jCheckBox1.setSelected(BackgroundEngine.recursiveExplore);
    jCheckBox1.addActionListener(new ShareAntPanel_jCheckBox1_actionAdapter(this));
    jButton3.setMaximumSize(new Dimension(150, 34));
    jButton3.setMinimumSize(new Dimension(150, 34));
    jButton3.setPreferredSize(new Dimension(150, 34));
    jButton3.setToolTipText(ji.JI.i("Close this tab"));
    //jButton3.setText(ji.JI.i("Close"));
    jButton3.setIcon(new LabelIcon(ji.JI.i("Close"),DoubleBuffer.getInstance().getButton(13), jButton3));
    jButton3.addActionListener(new ShareAntPanel_jButton3_actionAdapter(this));
    jLabel5.setToolTipText(ji.JI.i(""));
    jLabel5.setText("");
    jCheckBox2.setText("jCheckBox2");
    jCheckBox2.setPreferredSize(new Dimension(180, 23));
    jCheckBox2.setText(ji.JI.i("Share download path"));
    jCheckBox2.setSelected(BackgroundEngine.shareDownloadPath);
    if(BackgroundEngine.shareDownloadPath){
      WarriorAnt.checkDownloadPath();
      BackgroundEngine.getInstance().addDirectory(new File(WarriorAnt.downloadPath));
    }
    jCheckBox2.addActionListener(new ShareAntPanel_jCheckBox2_actionAdapter(this));
    jScrollPane1.getViewport().add(sharedFilesTable, null);
    jScrollPane2.getViewport().add(jList1, null);

    TableColumn column = null;
    for (int i = 0; i < model.getColumnCount(); i++) {
      column = sharedFilesTable.getColumnModel().getColumn(i);
      column.setPreferredWidth(columnSizes[i]);
    }

    jPanel1.add(jLabel2,    new XYConstraints(0, 0, -1, -1));
    jPanel1.add(jScrollPane2,         new XYConstraints(0, 25, -1, -1));
    jPanel1.add(jButton1,     new XYConstraints(410, 25, -1, -1));
    jPanel1.add(jButton2,       new XYConstraints(410, 80, -1, -1));
    jPanel1.add(jLabel3,         new XYConstraints(0, 220, -1, -1));
    jPanel1.add(jLabel4,    new XYConstraints(0, 160, -1, -1));
    jPanel1.add(jProgressBar1,     new XYConstraints(0, 180, -1, -1));
    jPanel1.add(jLabel5,          new XYConstraints(0, 240, -1, -1));
    jPanel1.add(jButton3,      new XYConstraints(540, 25, -1, -1));
    jPanel1.add(jCheckBox1,   new XYConstraints(540, 80, -1, -1));
    jPanel1.add(jCheckBox2,   new XYConstraints(540, 110, -1, -1));
    jPanel2.add(jLabel1,   new XYConstraints(0, 0, -1, -1));
    jPanel2.add(jScrollPane1,       new XYConstraints(0, 20, -1, -1));
    this.add(jPanel1, null);
    this.add(jPanel2, null);
  }

  public String sizeToString(double dSize){
    double currentSize = dSize;
    int x = 1;
    dSize = dSize / Math.pow(2, 20);
    while (dSize > 1 && x < 5) {
      dSize = dSize / Math.pow(2, 10);
      x++;
    }
    String suffix = " bytes";
    String size = currentSize+suffix;
    if (x == 2) {
      suffix = " Mib";
      size = (new Double(currentSize * 1.0 / Math.pow(2, 20))).
          toString();
      int index = size.indexOf(".");
      if (index >= 0)
        size = size.substring(0, index + 2);
      size += suffix;
    }
    if (x == 3) {
      suffix = " Gib";
      size = (new Double(currentSize * 1.0 / Math.pow(2, 30))).
          toString();
      int index = size.indexOf(".");
      if (index >= 0)
        size = size.substring(0, index + 2);
      size += suffix;
    }
    if (x == 4) {
      suffix = " Tib";
      size = (new Double(currentSize * 1.0 / Math.pow(2, 40))).
          toString();
      int index = size.indexOf(".");
      if (index >= 0)
        size = size.substring(0, index + 2);
      size += suffix;
    }
    return size;
  }

  public void propertyChange(PropertyChangeEvent e) {
    if (e.getPropertyName().equals("fileIndexingCompleted")) {
      this.jLabel5.setText(ji.JI.i("Total")+": " +
                           BackgroundEngine.getInstance().sharedFilesIndexHash.
                           size() + " "+ji.JI.i("files indexed")+"    "+ji.JI.i("Local")+"[" +
                           sizeToString(BackgroundEngine.getInstance().
                                        getTotalLocalSharedSize()) +
                           "]  "+ji.JI.i("Remote")+"[" +
                           sizeToString(BackgroundEngine.getInstance().getTotalRemoteSharedSize() +
                                        BackgroundEngine.getInstance().computeRemoteIndexedSharedSize()) +
                           "]  "+ji.JI.i("Known Supernodes")+"["+
                           BackgroundEngine.getInstance().getSupernodesSize()+"]");
      this.jLabel4.setVisible(false);
      this.jProgressBar1.setVisible(false);
      this.jLabel3.setForeground(Color.BLUE);
      this.jLabel3.setText(ji.JI.i("Status: file indexing completed... indexing engine idle."));
      Hashtable files = BackgroundEngine.getInstance().sharedFilesIndexName;
      Enumeration fileInfos = files.elements();
      ArrayList infos = new ArrayList();
      while(fileInfos.hasMoreElements()){
        infos.add(fileInfos.nextElement());
      }
      Collections.sort(infos, new FileInfosNameComparator());
      ((SharedFilesTableModel)(((TableSorter)sharedFilesTable.getModel())).getTableModel()).setSharedFiles(infos);
      this.sharedFilesTable.revalidate();
    }
    else if (e.getPropertyName().equals("fileIndexed")) {
      int filesToBeProcessed = ((Integer)e.getNewValue()).intValue();
      int fileTotalNumber = ((Integer)e.getOldValue()).intValue();
      this.jLabel5.setText(ji.JI.i("Progress")+": "+filesToBeProcessed+"/"+fileTotalNumber+ji.JI.i(" files"));
      Hashtable files = BackgroundEngine.getInstance().sharedFilesIndexName;
      Enumeration fileInfos = files.elements();
      ArrayList infos = new ArrayList();
      while(fileInfos.hasMoreElements()){
        infos.add(fileInfos.nextElement());
      }
      Collections.sort(infos, new FileInfosNameComparator());
      ((SharedFilesTableModel)(((TableSorter)sharedFilesTable.getModel())).getTableModel()).setSharedFiles(infos);
      this.sharedFilesTable.revalidate();
    }
    else if(e.getPropertyName().equals("fileIndexingInProgress")) {
      this.jLabel3.setText(ji.JI.i("Status: file indexing in progress... indexing may slow down your computer for a while!"));
      this.jLabel4.setVisible(true);
      this.jProgressBar1.setVisible(true);
      String fileName = (String)e.getOldValue();
      Integer progress = (Integer)e.getNewValue();
      this.jLabel4.setText(ji.JI.i("Indexing file")+": "+fileName);
      this.jProgressBar1.setValue(progress.intValue());
    }
    else if (e.getPropertyName().equals("fileIndexingInit")) {
      this.jProgressBar1.setValue(0);
      this.jLabel3.setText(ji.JI.i("Status: file indexing in progress... indexing may slow down your computer for a while!"));
      this.jLabel3.setForeground(Color.RED);
    }
    else if(e.getPropertyName().equals("SharedDirectoriesModification")){
      ArrayList sharedDirs = (ArrayList)BackgroundEngine.getInstance().sharedDirectories.clone();
      File downloadPath = new File(WarriorAnt.downloadPath);
      if (!sharedDirs.remove(new DirInfos(downloadPath.getAbsolutePath(), downloadPath.lastModified()))) {
        BackgroundEngine.shareDownloadPath = false;
        this.jCheckBox2.setSelected(false);
      }
      Object[] directories = sharedDirs.toArray();
      Arrays.sort(directories);
      this.jList1.setListData(directories);
    }
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (buffer != null){
      int posX = (this.getWidth() - 650)/2;
      int posY = (this.getHeight() - 550)/2;
      if(posX < 0) posX = 0;
      if(posY < 0) posY = 0;
      g.drawImage(buffer, posX, posY, this);
    }
  }

  void this_componentResized(ComponentEvent e) {
    this.jPanel1.setPreferredSize(new Dimension(e.getComponent().getWidth()-40,this.jPanel1.getHeight()));
    this.jPanel1.setSize(new Dimension(e.getComponent().getWidth()-40,this.jPanel1.getHeight()));

    this.jPanel2.setPreferredSize(new Dimension(e.getComponent().getWidth()-40, e.getComponent().getHeight()-this.jPanel1.getHeight()-40));
    this.jPanel2.setSize(new Dimension(e.getComponent().getWidth()-40, e.getComponent().getHeight()-this.jPanel1.getHeight()-40));

    this.jScrollPane1.setPreferredSize(new Dimension(this.getWidth()-80,this.getHeight()-this.jPanel1.getHeight()-80));
    this.jScrollPane1.setSize(new Dimension(this.getWidth()-80,this.getHeight()-this.jPanel1.getHeight()-80));
  }

  void jButton1_actionPerformed(ActionEvent e) {
    JFileChooser jfc = new JFileChooser();
    jfc.setMultiSelectionEnabled(true);
    jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = jfc.showDialog(this,ji.JI.i("Add Share Directory"));
    if(returnVal == JFileChooser.APPROVE_OPTION) {
       BackgroundEngine.getInstance().resetIndexingCycle();
       File[] toAdd = jfc.getSelectedFiles();
       for(int x = 0; x < toAdd.length; x++){
         BackgroundEngine.getInstance().addDirectory(toAdd[x]);
         BackgroundEngine.getInstance().storeLocal();
       }
    }
  }

  void jButton2_actionPerformed(ActionEvent e) {
    Object[] valuesDir = this.jList1.getSelectedValues();
    int[] indexesDir = this.jList1.getSelectedIndices();
    boolean reset = false;
    for (int x = 0; x < indexesDir.length; x++) {
      BackgroundEngine.getInstance().removeDirectory( ((DirInfos) valuesDir[x]).getFile());
      BackgroundEngine.getInstance().storeLocal();
      reset = true;
    }
    if(reset)
      BackgroundEngine.getInstance().resetIndexingCycle();
  }

  void jCheckBox1_actionPerformed(ActionEvent e) {
    BackgroundEngine.recursiveExplore = this.jCheckBox1.isSelected();
    this.caller.sap.storeSettings();
  }

  void editor_focusLost(FocusEvent e) {
    Component editor = (Component)e.getSource();
    FileInfos fi = (FileInfos)((SharedFilesTableModel)(((TableSorter)sharedFilesTable.getModel())).getTableModel()).sharedFiles.get(this.editedRow);
    fi.setComment( ((JTextField) editor).getText());
    editor.removeFocusListener(focusListener);
    this.editedRow = -1;
    BackgroundEngine.getInstance().storeLocal();
  }

  void sharedFilesTable_mousePressed(MouseEvent e) {
    if (e.getClickCount() == 1 &&
          (e.getButton() == MouseEvent.BUTTON3 ||
           (e.getButton() == MouseEvent.BUTTON1 && e.isControlDown()))) {
      int selectedRow = this.sharedFilesTable.getSelectedRow();
      if(selectedRow >= 0){
        TableSorter sorter = (TableSorter)this.sharedFilesTable.getModel();
        SharedFilesTableModel shareModel = (SharedFilesTableModel) sorter.
            getTableModel();
        FileInfos fileInfos = (FileInfos) shareModel.getSharedFiles().get(
            sorter.modelIndex(selectedRow));
        SharePopupMenu spm = new SharePopupMenu(this, fileInfos);
        spm.show(e.getComponent(), e.getX(), e.getY());
      }
    }else{
      JTextField editor = (JTextField)this.sharedFilesTable.getEditorComponent();
      if (editor != null) {
        this.editedRow = ( (TableSorter)this.sharedFilesTable.getModel()).modelIndex(this.sharedFilesTable.getEditingRow());
        editor.addFocusListener(focusListener);
      }
    }
  }

  void jButton3_actionPerformed(ActionEvent e) {
    this.caller.getTabbedPane().remove(this.caller.shareap);
  }

  void jCheckBox2_actionPerformed(ActionEvent e) {
    if(this.jCheckBox2.isSelected()){
      WarriorAnt.checkDownloadPath();
      BackgroundEngine.shareDownloadPath = true;
      BackgroundEngine.getInstance().addDirectory(new File(WarriorAnt.downloadPath));
    }else{
      BackgroundEngine.shareDownloadPath = false;
      BackgroundEngine.getInstance().removeDirectory(new File(WarriorAnt.downloadPath));
    }
    this.caller.sap.storeSettings();
    BackgroundEngine.getInstance().storeLocal();
  }
}

class ShareAntPanel_jButton1_actionAdapter implements java.awt.event.ActionListener {
  ShareAntPanel adaptee;

  ShareAntPanel_jButton1_actionAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jButton1_actionPerformed(e);
  }
}

class ShareAntPanel_jButton2_actionAdapter implements java.awt.event.ActionListener {
  ShareAntPanel adaptee;

  ShareAntPanel_jButton2_actionAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jButton2_actionPerformed(e);
  }
}

class ShareAntPanel_this_componentAdapter extends java.awt.event.ComponentAdapter {
  ShareAntPanel adaptee;

  ShareAntPanel_this_componentAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void componentResized(ComponentEvent e) {
    adaptee.this_componentResized(e);
  }
}

class ShareAntPanel_jCheckBox1_actionAdapter implements java.awt.event.ActionListener {
  ShareAntPanel adaptee;

  ShareAntPanel_jCheckBox1_actionAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jCheckBox1_actionPerformed(e);
  }
}

class ShareAntPanel_sharedFilesTable_mouseAdapter extends java.awt.event.MouseAdapter {
  ShareAntPanel adaptee;

  ShareAntPanel_sharedFilesTable_mouseAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void mousePressed(MouseEvent e) {
    adaptee.sharedFilesTable_mousePressed(e);
  }
}

class ShareAntPanel_jButton3_actionAdapter implements java.awt.event.ActionListener {
  ShareAntPanel adaptee;

  ShareAntPanel_jButton3_actionAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jButton3_actionPerformed(e);
  }
}

class SharedFiles_editor_focusAdapter extends java.awt.event.FocusAdapter {
  ShareAntPanel adaptee;

  SharedFiles_editor_focusAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void focusLost(FocusEvent e) {
    adaptee.editor_focusLost(e);
  }
}

class ShareAntPanel_jCheckBox2_actionAdapter implements java.awt.event.ActionListener {
  ShareAntPanel adaptee;

  ShareAntPanel_jCheckBox2_actionAdapter(ShareAntPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jCheckBox2_actionPerformed(e);
  }
}
